﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;
using Common;

namespace BusStationClient
{ 
    class CameraClass
    {
        private readonly SerialPort SerialPort = new SerialPort();        
        private readonly byte[] CommandStartImg =         
        { 0x40, 0x40, 0x61, 0x82, 0xff, 0xff, 0x00, 0x04, 0x0d, 0x0a };
        //=======包头======= 命令ID==摄像头编号===接收图像分包大小==结束======        
        private byte[] CommandGetImgData =
        { 0x40, 0x40, 0x62, 0x82, 0xff, 0xff, 0xff, 0xff, 0x0d, 0x0a };
        private List<byte> _data = new List<byte>();
        private List<byte> _package = new List<byte>();
        private readonly bool _isOpen = false;
        private string _stationName="";
        /// <summary>
        /// 拍照间隔时间(单位：秒)
        /// </summary>
        public  int TakePhotoSpaceTime = 600;        
        /// <summary>
        /// 摄像头是否成功开启
        /// </summary>
        public bool IsOpen
        {
            get { return _isOpen; }
        }

        public CameraClass(string serialName,string stationName)
        {
            try
            {
                
                SerialPort.PortName = serialName;
                SerialPort.BaudRate = 115200;
                if (SerialPort.IsOpen)
                {
                    SerialPort.Close();
                }
                SerialPort.Open();
                SerialPort.DataReceived += serialPort_DataReceived;      
                Thread threadSendCommand = new Thread(SendTakePhotoCommand);
                threadSendCommand.IsBackground = true;
                threadSendCommand.Start();
                _isOpen = true;
                _stationName = stationName;
                _stationName = _stationName.Replace(" ", "");
            }
            catch (Exception ex)
            {
                _isOpen = false;                
                LogService.WriteLog("摄像头串口初始化失败：" + ex.Message);
            }   
        }

        private void SendTakePhotoCommand()
        {
            while (true)
            {
                _data.Clear();
                _package.Clear();
                SerialPort.Write(CommandStartImg, 0, CommandStartImg.Length);    
                Thread.Sleep(TakePhotoSpaceTime*1000);
            }            
        }

        private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            try
            {
                byte[] readBuffer = new byte[SerialPort.BytesToRead];
                SerialPort.Read(readBuffer, 0, readBuffer.Length);
                if (readBuffer.Length == 0) return;
                //完整的数据包
                if (IsCompletePackage(readBuffer))
                {
                    _package.Clear();
                    _package.AddRange(readBuffer);
                    HandlePackage();
                }
                // 分包头部
                else if (IsPackageHead(readBuffer))
                {
                    _package.Clear();
                    _package.AddRange(readBuffer);
                }
                //分包尾部
                else if (IsPackageEnd(readBuffer))
                {
                    if (IsPackageHead(_package.ToArray()))
                    {
                        _package.AddRange(readBuffer);
                        if (IsCompletePackage(_package.ToArray()))
                        {
                            HandlePackage();
                        }
                        else
                        {
                            Console.WriteLine("收到尾部包，加入package后不为完整包...");
                        }
                    }
                    else
                    {
                        Console.WriteLine("收到尾部包，package内没有包头...");
                    }
                }
                else //中间数据
                {
                    if (IsPackageHead(_package.ToArray()))
                    {
                        _package.AddRange(readBuffer);
                    }
                    else
                    {
                        int ii = _index;
                        Console.WriteLine("收到不含头尾的包，package内没有包头...");
                    }
                }
            }
            catch (Exception ex)
            {
                LogService.WriteLog("摄像头串口接受数据处异常："+ex.Message);
            }
           
        }

        private void HandlePackage()
        {
            try
            {
                byte index = _package[3];
                byte[] imgData = GetImgDataFromPackage(_package.ToArray());

                if (index == 00) //第一个包
                {
                    _data.Clear();
                    _index = 0;
                    _index++;
                    _data.AddRange(imgData);
                    byte[] commandNextPg = CommandGetImgData;
                    SerialPort.Write(commandNextPg, 0, commandNextPg.Length);
                }
                else
                {
                    //if (index == _index)
                    // {
                    _data.AddRange(imgData);
                    //最后一个包    保存图片
                    if (_package[_package.Count - 5] == 0xFF &&
                        _package[_package.Count - 4] == 0xD9)
                    {
                        try
                        {
                            MemoryStream stream = new MemoryStream(_data.ToArray(), true);
                            Image img = Image.FromStream(stream);
                            string fileName = _stationName +
                                DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + ".jpg";
                            string path = Environment.CurrentDirectory + "\\Images";
                            if (!Directory.Exists(path))
                            {
                                Directory.CreateDirectory(path);
                            }
                            //path +=  +_stationName+imgName + ".jpg";
                            //wh.cityofcar.com  cameraPhoto  otech123456
                            img.Save(path + "\\" + fileName);
                            FtpHelper.UploadFtp(path, fileName, "wh.cityofcar.com",
                                "cameraPhoto", "otech123456");
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("保存图片失败..." + ex.Message);
                        }
                    }
                    else//中间的包
                    {
                        _index++;
                        byte[] commandNextPg = CommandGetImgData;
                        SerialPort.Write(commandNextPg, 0, commandNextPg.Length);
                    }
                    //}
                }
                _package.Clear();
            }
            catch (Exception ex)
            {
                LogService.WriteLog("摄像头处理分包处异常："+ex.Message);
            }        
        }

        private int _index = -1;

        private bool IsCompletePackage(byte[] data)
        {
            // 0  1  2    3  4      5  6        7     8  9   L-5 L-4    L-3     L-2 L-1
            //==包头=======位置======帧的大小=====256=======图像数据=======校验和======结束===
            //40 40 63    KK KK     xx xx       FF    FF D8...FF D9   一个字节     0D 0A
            //            00 00    00 04(1024字节)       有效数据8至L-4 
            //------------01 00 ----------------------包含FF D8及FF D9--------------
            //检验长度
            if (data.Length < 15)
            {
                return false;
            }
            int len = data.Length;
            //检验固定byte是否正确
            if (data[0] != 0x40 || data[1] != 0x40 || data[2] != 0x63 || data[7] != 0xFF
                || data[len - 1] != 0x0A || data[len - 2] != 0x0D)
            {
                return false;
            }
            return true;
        }

        private byte[] GetImgDataFromPackage(byte[] packege)
        {
            byte[] data;
            if (packege[3] == 0x00) // 第一个包
            {
                data = new byte[packege.Length - 11];
                Array.Copy(packege, 8, data, 0, data.Length);

            }
            else if (packege[packege.Length - 5] == 0xFF //最后一个包
                && packege[packege.Length - 4] == 0xD9)
            {
                data = new byte[packege.Length - 11];
                Array.Copy(packege, 8, data, 0, data.Length);
            }
            else//中间的包
            {
                data = new byte[packege.Length - 11];
                Array.Copy(packege, 8, data, 0, data.Length);
            }        
            return data;
        }

        private bool IsPackageHead(byte[] data)
        {
            if (data.Length < 8) return false;          
            if (data[0] != 0x40 || data[1] != 0x40 || data[2] != 0x63                
               || data[7] != 0xff)
            {
                return false;
            }
            return true;
        }

        private bool IsPackageEnd(byte[] data)
        {
            if (data.Length < 2) return false;
            if (data[data.Length - 1] != 0x0a || data[data.Length - 2] != 0x0d)
            {
                return false;
            }
            return true;
        }
    }
}
